# -*- coding:binary -*-
require 'spec_helper'

require 'rex/java/serialization'
require 'rex/proto/rmi'
require 'msf/core/exploit/java/rmi/client'

RSpec.describe Msf::Exploit::Remote::Java::Rmi::Client::Registry do

  include_context "Msf::StringIO"

  let(:name) do
    'jmxrmi'
  end

  let(:interface_class) do
    'javax.management.remote.rmi.RMIServerImpl_Stub'
  end

  subject(:mod) do
    mod = ::Msf::Exploit.new
    mod.extend ::Msf::Exploit::Remote::Java::Rmi::Client
    mod.send(:initialize)
    mod
  end

  describe "#send_registry_list" do
    context "when there aren't names registered" do
      let(:list_empty_response) {
        "\x51\xac\xed\x00\x05\x77\x0f\x01\xbb\x2e\x19\xae\x00\x00\x01\x4c" +
          "\x32\xa9\x92\x56\x80\x04\x75\x72\x00\x13\x5b\x4c\x6a\x61\x76\x61" +
          "\x2e\x6c\x61\x6e\x67\x2e\x53\x74\x72\x69\x6e\x67\x3b\xad\xd2\x56" +
          "\xe7\xe9\x1d\x7b\x47\x02\x00\x00\x70\x78\x70\x00\x00\x00\x00"
      }

      it "returns empty array" do
        msf_io.msf_data = list_empty_response
        expect(mod.send_registry_list(sock: msf_io)).to eq([])
      end
    end

    context "when there are names registered" do
      let(:list_with_names_response) {
        "\x51\xac\xed\x00\x05\x77\x0f\x01\x82\x73\x92\x35\x00\x00\x01\x4c" +
          "\x48\x27\x84\x49\x80\xb9\x75\x72\x00\x13\x5b\x4c\x6a\x61\x76\x61" +
          "\x2e\x6c\x61\x6e\x67\x2e\x53\x74\x72\x69\x6e\x67\x3b\xad\xd2\x56" +
          "\xe7\xe9\x1d\x7b\x47\x02\x00\x00\x70\x78\x70\x00\x00\x00\x01\x74" +
          "\x00\x06\x6a\x6d\x78\x72\x6d\x69"
      }

      it "returns the list of registered names" do
        msf_io.msf_data = list_with_names_response
        expect(mod.send_registry_list(sock: msf_io)).to eq([name])
      end
    end

  end

  describe "#send_registry_lookup" do
    context "when there isn't an interface bound" do
      let(:lookup_exception) {
        "\x51\xac\xed\x00\x05\x77\x0f\x02\x82\x73\x92\x35\x00\x00\x01\x4c" +
          "\x48\x27\x84\x49\x80\xbc\x73\x72\x00\x1a\x6a\x61\x76\x61\x2e\x72" +
          "\x6d\x69\x2e\x4e\x6f\x74\x42\x6f\x75\x6e\x64\x45\x78\x63\x65\x70" +
          "\x74\x69\x6f\x6e\xe6\x37\xf9\xa7\x2d\x7c\x3a\xfb\x02\x00\x00\x70" +
          "\x78\x72\x00\x13\x6a\x61\x76\x61\x2e\x6c\x61\x6e\x67\x2e\x45\x78" +
          "\x63\x65\x70\x74\x69\x6f\x6e\xd0\xfd\x1f\x3e\x1a\x3b\x1c\xc4\x02" +
          "\x00\x00\x70\x78\x72\x00\x13\x6a\x61\x76\x61\x2e\x6c\x61\x6e\x67" +
          "\x2e\x54\x68\x72\x6f\x77\x61\x62\x6c\x65\xd5\xc6\x35\x27\x39\x77" +
          "\xb8\xcb\x03\x00\x04\x4c\x00\x05\x63\x61\x75\x73\x65\x74\x00\x15" +
          "\x4c\x6a\x61\x76\x61\x2f\x6c\x61\x6e\x67\x2f\x54\x68\x72\x6f\x77" +
          "\x61\x62\x6c\x65\x3b\x4c\x00\x0d\x64\x65\x74\x61\x69\x6c\x4d\x65" +
          "\x73\x73\x61\x67\x65\x74\x00\x12\x4c\x6a\x61\x76\x61\x2f\x6c\x61" +
          "\x6e\x67\x2f\x53\x74\x72\x69\x6e\x67\x3b\x5b\x00\x0a\x73\x74\x61" +
          "\x63\x6b\x54\x72\x61\x63\x65\x74\x00\x1e\x5b\x4c\x6a\x61\x76\x61" +
          "\x2f\x6c\x61\x6e\x67\x2f\x53\x74\x61\x63\x6b\x54\x72\x61\x63\x65" +
          "\x45\x6c\x65\x6d\x65\x6e\x74\x3b\x4c\x00\x14\x73\x75\x70\x70\x72" +
          "\x65\x73\x73\x65\x64\x45\x78\x63\x65\x70\x74\x69\x6f\x6e\x73\x74" +
          "\x00\x10\x4c\x6a\x61\x76\x61\x2f\x75\x74\x69\x6c\x2f\x4c\x69\x73" +
          "\x74\x3b\x70\x78\x70\x71\x00\x7e\x00\x07\x74\x00\x2f\x4e\x6f\x74" +
          "\x20\x62\x6f\x75\x6e\x64\x3a\x20\x22\x74\x65\x73\x74\x22\x20\x28" +
          "\x6f\x6e\x6c\x79\x20\x62\x6f\x75\x6e\x64\x20\x6e\x61\x6d\x65\x20" +
          "\x69\x73\x20\x22\x6a\x6d\x78\x72\x6d\x69\x22\x29\x75\x72\x00\x1e" +
          "\x5b\x4c\x6a\x61\x76\x61\x2e\x6c\x61\x6e\x67\x2e\x53\x74\x61\x63" +
          "\x6b\x54\x72\x61\x63\x65\x45\x6c\x65\x6d\x65\x6e\x74\x3b\x02\x46" +
          "\x2a\x3c\x3c\xfd\x22\x39\x02\x00\x00\x70\x78\x70\x00\x00\x00\x0e" +
          "\x73\x72\x00\x1b\x6a\x61\x76\x61\x2e\x6c\x61\x6e\x67\x2e\x53\x74" +
          "\x61\x63\x6b\x54\x72\x61\x63\x65\x45\x6c\x65\x6d\x65\x6e\x74\x61" +
          "\x09\xc5\x9a\x26\x36\xdd\x85\x02\x00\x04\x49\x00\x0a\x6c\x69\x6e" +
          "\x65\x4e\x75\x6d\x62\x65\x72\x4c\x00\x0e\x64\x65\x63\x6c\x61\x72" +
          "\x69\x6e\x67\x43\x6c\x61\x73\x73\x71\x00\x7e\x00\x04\x4c\x00\x08" +
          "\x66\x69\x6c\x65\x4e\x61\x6d\x65\x71\x00\x7e\x00\x04\x4c\x00\x0a" +
          "\x6d\x65\x74\x68\x6f\x64\x4e\x61\x6d\x65\x71\x00\x7e\x00\x04\x70" +
          "\x78\x70\xff\xff\xff\xff\x74\x00\x2c\x73\x75\x6e\x2e\x6d\x61\x6e" +
          "\x61\x67\x65\x6d\x65\x6e\x74\x2e\x6a\x6d\x78\x72\x65\x6d\x6f\x74" +
          "\x65\x2e\x53\x69\x6e\x67\x6c\x65\x45\x6e\x74\x72\x79\x52\x65\x67" +
          "\x69\x73\x74\x72\x79\x70\x74\x00\x06\x6c\x6f\x6f\x6b\x75\x70\x73" +
          "\x71\x00\x7e\x00\x0b\xff\xff\xff\xff\x74\x00\x22\x73\x75\x6e\x2e" +
          "\x72\x6d\x69\x2e\x72\x65\x67\x69\x73\x74\x72\x79\x2e\x52\x65\x67" +
          "\x69\x73\x74\x72\x79\x49\x6d\x70\x6c\x5f\x53\x6b\x65\x6c\x70\x74" +
          "\x00\x08\x64\x69\x73\x70\x61\x74\x63\x68\x73\x71\x00\x7e\x00\x0b" +
          "\xff\xff\xff\xff\x74\x00\x1f\x73\x75\x6e\x2e\x72\x6d\x69\x2e\x73" +
          "\x65\x72\x76\x65\x72\x2e\x55\x6e\x69\x63\x61\x73\x74\x53\x65\x72" +
          "\x76\x65\x72\x52\x65\x66\x70\x74\x00\x0b\x6f\x6c\x64\x44\x69\x73" +
          "\x70\x61\x74\x63\x68\x73\x71\x00\x7e\x00\x0b\xff\xff\xff\xff\x71" +
          "\x00\x7e\x00\x13\x70\x71\x00\x7e\x00\x11\x73\x71\x00\x7e\x00\x0b" +
          "\xff\xff\xff\xff\x74\x00\x1d\x73\x75\x6e\x2e\x72\x6d\x69\x2e\x74" +
          "\x72\x61\x6e\x73\x70\x6f\x72\x74\x2e\x54\x72\x61\x6e\x73\x70\x6f" +
          "\x72\x74\x24\x31\x70\x74\x00\x03\x72\x75\x6e\x73\x71\x00\x7e\x00" +
          "\x0b\xff\xff\xff\xff\x71\x00\x7e\x00\x17\x70\x71\x00\x7e\x00\x18" +
          "\x73\x71\x00\x7e\x00\x0b\xff\xff\xff\xfe\x74\x00\x1e\x6a\x61\x76" +
          "\x61\x2e\x73\x65\x63\x75\x72\x69\x74\x79\x2e\x41\x63\x63\x65\x73" +
          "\x73\x43\x6f\x6e\x74\x72\x6f\x6c\x6c\x65\x72\x70\x74\x00\x0c\x64" +
          "\x6f\x50\x72\x69\x76\x69\x6c\x65\x67\x65\x64\x73\x71\x00\x7e\x00" +
          "\x0b\xff\xff\xff\xff\x74\x00\x1b\x73\x75\x6e\x2e\x72\x6d\x69\x2e" +
          "\x74\x72\x61\x6e\x73\x70\x6f\x72\x74\x2e\x54\x72\x61\x6e\x73\x70" +
          "\x6f\x72\x74\x70\x74\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x43\x61" +
          "\x6c\x6c\x73\x71\x00\x7e\x00\x0b\xff\xff\xff\xff\x74\x00\x22\x73" +
          "\x75\x6e\x2e\x72\x6d\x69\x2e\x74\x72\x61\x6e\x73\x70\x6f\x72\x74" +
          "\x2e\x74\x63\x70\x2e\x54\x43\x50\x54\x72\x61\x6e\x73\x70\x6f\x72" +
          "\x74\x70\x74\x00\x0e\x68\x61\x6e\x64\x6c\x65\x4d\x65\x73\x73\x61" +
          "\x67\x65\x73\x73\x71\x00\x7e\x00\x0b\xff\xff\xff\xff\x74\x00\x34" +
          "\x73\x75\x6e\x2e\x72\x6d\x69\x2e\x74\x72\x61\x6e\x73\x70\x6f\x72" +
          "\x74\x2e\x74\x63\x70\x2e\x54\x43\x50\x54\x72\x61\x6e\x73\x70\x6f" +
          "\x72\x74\x24\x43\x6f\x6e\x6e\x65\x63\x74\x69\x6f\x6e\x48\x61\x6e" +
          "\x64\x6c\x65\x72\x70\x74\x00\x04\x72\x75\x6e\x30\x73\x71\x00\x7e" +
          "\x00\x0b\xff\xff\xff\xff\x71\x00\x7e\x00\x24\x70\x71\x00\x7e\x00" +
          "\x18\x73\x71\x00\x7e\x00\x0b\xff\xff\xff\xff\x74\x00\x27\x6a\x61" +
          "\x76\x61\x2e\x75\x74\x69\x6c\x2e\x63\x6f\x6e\x63\x75\x72\x72\x65" +
          "\x6e\x74\x2e\x54\x68\x72\x65\x61\x64\x50\x6f\x6f\x6c\x45\x78\x65" +
          "\x63\x75\x74\x6f\x72\x70\x74\x00\x09\x72\x75\x6e\x57\x6f\x72\x6b" +
          "\x65\x72\x73\x71\x00\x7e\x00\x0b\xff\xff\xff\xff\x74\x00\x2e\x6a" +
          "\x61\x76\x61\x2e\x75\x74\x69\x6c\x2e\x63\x6f\x6e\x63\x75\x72\x72" +
          "\x65\x6e\x74\x2e\x54\x68\x72\x65\x61\x64\x50\x6f\x6f\x6c\x45\x78" +
          "\x65\x63\x75\x74\x6f\x72\x24\x57\x6f\x72\x6b\x65\x72\x70\x71\x00" +
          "\x7e\x00\x18\x73\x71\x00\x7e\x00\x0b\xff\xff\xff\xff\x74\x00\x10" +
          "\x6a\x61\x76\x61\x2e\x6c\x61\x6e\x67\x2e\x54\x68\x72\x65\x61\x64" +
          "\x70\x71\x00\x7e\x00\x18\x73\x72\x00\x26\x6a\x61\x76\x61\x2e\x75" +
          "\x74\x69\x6c\x2e\x43\x6f\x6c\x6c\x65\x63\x74\x69\x6f\x6e\x73\x24" +
          "\x55\x6e\x6d\x6f\x64\x69\x66\x69\x61\x62\x6c\x65\x4c\x69\x73\x74" +
          "\xfc\x0f\x25\x31\xb5\xec\x8e\x10\x02\x00\x01\x4c\x00\x04\x6c\x69" +
          "\x73\x74\x71\x00\x7e\x00\x06\x70\x78\x72\x00\x2c\x6a\x61\x76\x61" +
          "\x2e\x75\x74\x69\x6c\x2e\x43\x6f\x6c\x6c\x65\x63\x74\x69\x6f\x6e" +
          "\x73\x24\x55\x6e\x6d\x6f\x64\x69\x66\x69\x61\x62\x6c\x65\x43\x6f" +
          "\x6c\x6c\x65\x63\x74\x69\x6f\x6e\x19\x42\x00\x80\xcb\x5e\xf7\x1e" +
          "\x02\x00\x01\x4c\x00\x01\x63\x74\x00\x16\x4c\x6a\x61\x76\x61\x2f" +
          "\x75\x74\x69\x6c\x2f\x43\x6f\x6c\x6c\x65\x63\x74\x69\x6f\x6e\x3b" +
          "\x70\x78\x70\x73\x72\x00\x13\x6a\x61\x76\x61\x2e\x75\x74\x69\x6c" +
          "\x2e\x41\x72\x72\x61\x79\x4c\x69\x73\x74\x78\x81\xd2\x1d\x99\xc7" +
          "\x61\x9d\x03\x00\x01\x49\x00\x04\x73\x69\x7a\x65\x70\x78\x70\x00" +
          "\x00\x00\x00\x77\x04\x00\x00\x00\x00\x78\x71\x00\x7e\x00\x33\x78"
      }
      it "raises an Rex::Proto::Rmi::Exception" do
        msf_io.msf_data = lookup_exception
        expect { mod.send_registry_lookup(sock: msf_io, name: 'test') }.to raise_error(Rex::Proto::Rmi::Exception)
      end
    end

    context "when there is an interface bound" do
      let(:lookup_response) {
        "\x51\xac\xed\x00\x05\x77\x0f\x01\x82\x73\x92\x35\x00\x00\x01\x4c" +
          "\x48\x27\x84\x49\x80\xba\x73\x72\x00\x2e\x6a\x61\x76\x61\x78\x2e" +
          "\x6d\x61\x6e\x61\x67\x65\x6d\x65\x6e\x74\x2e\x72\x65\x6d\x6f\x74" +
          "\x65\x2e\x72\x6d\x69\x2e\x52\x4d\x49\x53\x65\x72\x76\x65\x72\x49" +
          "\x6d\x70\x6c\x5f\x53\x74\x75\x62\x00\x00\x00\x00\x00\x00\x00\x02" +
          "\x02\x00\x00\x70\x78\x72\x00\x1a\x6a\x61\x76\x61\x2e\x72\x6d\x69" +
          "\x2e\x73\x65\x72\x76\x65\x72\x2e\x52\x65\x6d\x6f\x74\x65\x53\x74" +
          "\x75\x62\xe9\xfe\xdc\xc9\x8b\xe1\x65\x1a\x02\x00\x00\x70\x78\x72" +
          "\x00\x1c\x6a\x61\x76\x61\x2e\x72\x6d\x69\x2e\x73\x65\x72\x76\x65" +
          "\x72\x2e\x52\x65\x6d\x6f\x74\x65\x4f\x62\x6a\x65\x63\x74\xd3\x61" +
          "\xb4\x91\x0c\x61\x33\x1e\x03\x00\x00\x70\x78\x70\x77\x37\x00\x0a" +
          "\x55\x6e\x69\x63\x61\x73\x74\x52\x65\x66\x00\x0e\x31\x37\x32\x2e" +
          "\x31\x36\x2e\x31\x35\x38\x2e\x31\x33\x32\x00\x00\x13\x26\xa0\x59" +
          "\x9d\x0d\x09\xd3\x01\xbd\x82\x73\x92\x35\x00\x00\x01\x4c\x48\x27" +
          "\x84\x49\x80\x01\x01\x78"
      }

      it "returns the reference information" do
        msf_io.msf_data = lookup_response
        expect(mod.send_registry_lookup(sock: msf_io, name: name)[:object]).to eq(interface_class)
      end
    end
  end

  describe "#registry_interface_hash" do
    it "calculates the hash for the java/rmi/registry/RegistryImpl_Stub correctly" do
      expect(mod.registry_interface_hash).to eq(4905912898345647071)
    end
  end
end

